package main

import (
	"container/list"
	"fmt"
)

/*
用两个栈实现一个队列。队列的声明如下，请实现它的两个函数 appendTail 和 deleteHead ，
分别完成在队列尾部插入整数和在队列头部删除整数的功能。
(若队列中没有元素，deleteHead操作返回 -1 )

示例 1：
输入：
["CQueue","appendTail","deleteHead","deleteHead"]
[[],[3],[],[]]
输出：[null,null,3,-1]
示例 2：
输入：
["CQueue","deleteHead","appendTail","appendTail","deleteHead","deleteHead"]
[[],[],[5],[2],[],[]]
输出：[null,-1,null,null,5,2]
提示：
1 <= values <= 10000
最多会对appendTail、deleteHead 进行10000次调用

 */
type CQueue struct {
	//入
	stack1 []int
	 //出
	stack2 []int

}

func Constructor() CQueue {
	return CQueue{stack1: []int{}, stack2: []int{}}
}


func (this *CQueue) AppendTail(value int)  {
	this.stack1 = append(this.stack1[:], value)
}


func (this *CQueue) DeleteHead() int {
	if len(this.stack2) == 0 && len(this.stack1) == 0 {
		return -1
	}else if len(this.stack2) == 0 && len(this.stack1) > 0 {
		l := len(this.stack1) - 1
		for len(this.stack1) > 0 {
			val := this.stack1[l]
			this.stack1 = this.stack1[:l]
			l--
			this.stack2 = append(this.stack2,val)
		}
	}
	r := this.stack2[len(this.stack2) - 1]
	this.stack2 = this.stack2[:len(this.stack2) - 1]
	return r
}


//方法二
type CQueue2 struct {
	stack1, stack2 *list.List
}

func Constructor2() CQueue2 {
	return CQueue2{
		stack1: list.New(),
		stack2: list.New(),
	}
}

func (this *CQueue2) AppendTail2(value int)  {
	this.stack1.PushBack(value)
}

func (this *CQueue2) DeleteHead2() int {
	// 如果第二个栈为空
	if this.stack2.Len() == 0 {
		for this.stack1.Len() > 0 {
			this.stack2.PushBack(this.stack1.Remove(this.stack1.Back()))
		}
	}
	if this.stack2.Len() != 0 {
		e := this.stack2.Back()
		this.stack2.Remove(e)
		return e.Value.(int)
	}
	return -1
}

func main() {
	obj := Constructor()
	obj.AppendTail(3)
	obj.AppendTail(2)
	obj.AppendTail(3)
	obj.AppendTail(5)
	obj.AppendTail(7)

	param_2 := obj.DeleteHead()
	fmt.Println(param_2)

	param_2 = obj.DeleteHead()
	fmt.Println(param_2)

	param_2 = obj.DeleteHead()
	fmt.Println(param_2)

}
/**
 * Your CQueue object will be instantiated and called as such:
 * obj := Constructor();
 * obj.AppendTail(value);
 * param_2 := obj.DeleteHead();
 */


